package top.lishuoboy.spring.config;

import cn.hutool.core.collection.CollUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Controller;
import top.lishuoboy.dependency.base.bean.User;
import top.lishuoboy.spring.bean.School;
import top.lishuoboy.spring.bean.Student2;
import top.lishuoboy.spring.bean.Student4;
import top.lishuoboy.spring.bean.Student5_1;
import top.lishuoboy.spring.bean_di.Student10;
import top.lishuoboy.spring.bean_di.Student7;
import top.lishuoboy.spring.bean_di.Student8;
import top.lishuoboy.spring.bean_di.Student9;
import top.lishuoboy.spring.bean_other.Student18_1;
import top.lishuoboy.spring.profile.MyDataSource;

@Profile({"default", "dev", "test"})   // 指定类里面所有的@Bean的激活环境
@EnableAspectJAutoProxy  // 开启AOP Aspect自动代理
@PropertySource(value = {"classpath:spring/import1.properties", "classpath:spring/import2.properties"}, encoding = "UTF8", ignoreResourceNotFound = false)
//@Lazy 设置全局懒加载。该配置类的@bean全是懒加载
@Import(value = {MyImportConfiguration.class})
@ComponentScan(basePackages = "top.lishuoboy.spring", lazyInit = false  // 设置全局懒加载。该basePackages的bean全是懒加载
    , useDefaultFilters = true      // 默认 Filters 会扫描 @Component、@Repository、@Service、@Controller，使用 includeFilters只包含这四个注解一部分时需要设为 false
    , excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})}
)
public class ApplicationConfig {
    @Bean
    School school() {
        return new School();
    }

    @Bean
    /** 3.bean作用域scope，多例：prototype */
    @Scope("prototype")
    Student2 student2() {
        return new Student2();
    }

    /** 4.bean生命周期 */
    @Bean(initMethod = "init", destroyMethod = "destroy")
    Student4 student4() {
        return new Student4();
    }

    /* 5.懒加载。value 默认为 true */
    @Lazy
    @Bean
    Student5_1 student5_1() {
        return new Student5_1();
    }

    /** 7.构造器注入 */
    @Bean
    Student7 student7(User user) {
        return new Student7("张三", user);
    }

    @Bean
    User user() {
        return new User();
    }

    /** 8.Setter注入 */
    @Bean
    Student8 student8(User user) {
        Student8 student8 = new Student8();
        student8.setStudentName("张三");
        student8.setUser(user);
        return student8;
    }

    /** 9.依赖注入——Setter内部bean方式注入 */
    @Bean
    Student9 student9() {
        Student9 student9 = new Student9();
        student9.setStudentName("张三");
        student9.setUser(new User());
        return student9;
    }

    /** 10.依赖注入——Setter注入 容器：Array、List、Set、Map、Properties。类必须有对应参数的Setter 和 空参构造器 */
    @Bean
    Student10 student10() {
        Student10 student10 = new Student10();
        student10.setArray(null);
        student10.setList(null);
        student10.setSet(null);
        student10.setMap(null);
        student10.setProps(null);
        return student10;
    }

    /** 18.引入外部properties文件 @PropertySource / <context:property-placeholder/> */
    @Bean
//    @Value("${name}")  // 用在方法上，对所有方法参数有效
    Student18_1 student18_1(@Value("${name}") String name, @Value("${set[0]}") String set_0, @Value("${set[1]}") String set_1) {
        Student18_1 student18_1 = new Student18_1();
        student18_1.setName(name);
        student18_1.setSet(CollUtil.set(false, set_0, set_1));
        return student18_1;
    }

    @Bean
    @Profile("default")
    MyDataSource myDataSourceDefault() {
        return MyDataSource.builder().user("user-default").build();
    }

    @Bean
    @Profile("dev")
    MyDataSource myDataSourceDev() {
        return MyDataSource.builder().user("user-dev").build();
    }

    @Bean
    @Profile("test")
    MyDataSource myDataSourceTest() {
        return MyDataSource.builder().user("user-test").build();
    }
}